package cn.wolfcode.wolf2w.business.service.impl;

import cn.wolfcode.wolf2w.api.domain.Destination;
import cn.wolfcode.wolf2w.api.domain.Region;
import cn.wolfcode.wolf2w.business.mapper.DestinationMapper;
import cn.wolfcode.wolf2w.business.mapper.RegionMapper;
import cn.wolfcode.wolf2w.business.query.DestinationQuery;
import cn.wolfcode.wolf2w.business.service.IDestinationService;
import cn.wolfcode.wolf2w.common.redis.service.RedisService;
import cn.wolfcode.wolf2w.common.redis.util.RedisKeys;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 目的地Service业务层处理
 *
 * @author 浪兎兎
 * @date 2025-05-30
 */
@Service
@Transactional
public class DestinationServiceImpl extends ServiceImpl<DestinationMapper, Destination> implements IDestinationService {

    @Autowired
    private RegionMapper regionMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public IPage<Destination> queryPage(DestinationQuery qo) {
        IPage<Destination> page = new Page<>(qo.getCurrentPage(), qo.getPageSize());
        return lambdaQuery()
                .page(page);
    }

    @Override
    public List<Destination> search(Long regionId) {
        List<Destination> dests;
        if (regionId == -1) {
            dests = lambdaQuery().eq(Destination::getParentId, 1).list();
        } else {
            Region region = regionMapper.selectById(regionId);
            String refIds = region.getRefIds();
            String[] split = refIds.split(",");
            List<Long> ids = Arrays.stream(split).map(Long::valueOf).collect(Collectors.toList());
            dests = lambdaQuery().in(Destination::getId, ids).list();
        }
        for (Destination dest : dests) {
            Long id = dest.getId();
            List<Destination> list = lambdaQuery().eq(Destination::getParentId, id).list();
            dest.setChildren(list);
        }
        return dests;
    }

    @Override
    public List<Destination> toasts(Long destId) {
        List<Destination> destinations = new ArrayList<>();
        createToasts(destId, destinations);
        return destinations;
    }

    @Override
    public List<Destination> destinationList(String name, Integer type) {
        LambdaQueryWrapper<Destination> wrapper = new LambdaQueryWrapper<>();
        if (name != null) {
            wrapper.like(Destination::getName, name);
        }
        if (type != null && type != 2) {
            Set<Long> domesticDestinations = domesticDestination(new HashSet<Long>() {{ this.add(1L); }}, new HashSet<>());
            if (type == -1) {
                wrapper.in(Destination::getId, domesticDestinations);
            } else if (type == 1) {
                wrapper.notIn(Destination::getId, domesticDestinations);
            }
        }
        return baseMapper.selectList(wrapper);
    }

    @Override
    public void reSendDestMessage() {
        long now = System.currentTimeMillis();
        long max = now - 60*1000;
        String key = RedisKeys.MQ_MESSAGE.join("destination");
        Set set = redisService.rangeCacheZsetByScore(key, 0, max);
        for (Object o : set) {
            String message = (String) o;
            amqpTemplate.convertAndSend("destinationExchange", "", message);
        }
    }

    /**
     * 返回在国内的集合
     */
    private Set<Long> domesticDestination(Set<Long> ids, Set<Long> results) {
        // 查询
        LambdaQueryWrapper<Destination> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Destination::getId);
        wrapper.in(Destination::getParentId, ids);
        List<Destination> destinations = baseMapper.selectList(wrapper);
        // 将 ids 置入结果
        results.addAll(ids);
        ids.clear();
        // 将查询出来的数据放入 ids
        for (Destination destination : destinations) {
            ids.add(destination.getId());
        }
        // 如果 ids 不为空，则继续执行函数
        if (ids.size() != 0) {
            domesticDestination(ids, results);
        }
        return results;
    }

    private void createToasts(Long destId, List<Destination> list) {
        if (destId == null) return;
        Destination destination = baseMapper.selectById(destId);
        Long parentId = destination.getParentId();
        createToasts(parentId, list);
        list.add(destination);
    }
}
